#!/usr/bin/env python
'''
'''

try:
    import psyco
    psyco.profile()
except:
    pass

import os, sys, time, random, math, Lumpy, pgu.gui.slider

try:
    import pygame
    from pygame.locals import *
except:
    if 'pythonw' in sys.executable:
        from Tkinter import *
        tk = Tk()
        Label(tk, text='You need pygame to play pygorillas.\n get it here:').pack()
        s = StringVar()
        s.set('http://pygame.org')
        Entry(tk, textvariable=s).pack()
        tk.mainloop()
    else:
        print "You need pygame to play this game: http://www.pygame.org/"
    sys.exit(1)
    pygame.font.init()

WIDTH = 1400
HEIGHT = 1050
BG_COLOR = (0,0,255)
FONT = ('courier', 18)
CUBICLE_WIDTH = 25
CUBICLE_HEIGHT = 20

   #Provides the locations of the images for the clouds, sun, building, and gorillas. Not OS sensitive.
CLOUD_IMAGE_FILENAME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'cloud')
SUN_IMAGE_FILENAME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'sun.png')
BUILDING_IMAGE_FILENAME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'building.png')
GORILLA_IMAGE_FILENAME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'gorilla.png')
QUIT_KEY = K_ESCAPE   
TEXT_POSITION = ((WIDTH/2-300), (200))

def load_image(fullname, colorkey=None):
    ''' example: self.image, self.rect = load_image(CLOUD_IMAGE_FILENAME)
    '''
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'Cannot load image:', fullname
        raise SystemExit, message
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()
    
class Banana(object):
    '''Creates the banana objects, places them relative to the gorillas
    '''
    def __init__(self, bg, gorilla_a_building):
        self.rect = pygame.draw.arc(bg, (236, 236, 14), pygame.Rect(125, (gorilla_a_building.rect.top - 95), 40, 40), 0, ((7*math.pi)/9), 9)
        self.x = 125
        self.y = (gorilla_a_building.rect.top - 95)
        self.dx = 0
        self.dy = 0
    
    def draw(self, bg):
        self.rect = pygame.draw.arc(bg, (236, 236, 14), pygame.Rect(self.x, self.y, 40, 40), 0, ((7*math.pi)/9), 9)
        return self.rect

class Gorilla(pygame.sprite.Sprite):
    '''creates the Gorilla sprites, places the bottom left corner of the rectangle at the given coordinates
    '''
    def __init__(self, x_pos, y_pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image(GORILLA_IMAGE_FILENAME)
        self.area = pygame.display.get_surface().get_rect()
        self.rect.bottomleft = (x_pos, y_pos)
            
class Building(pygame.sprite.Sprite):
    ''' creates the Gorilla sprites, places the bottom left corner of the rectangle at the given coordinates
    '''
    def __init__(self, x_pos, y_pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image(BUILDING_IMAGE_FILENAME)
        self.area = pygame.display.get_surface().get_rect()
        self.rect.bottomleft = (x_pos, y_pos)
        self.collision_rects = [self.rect]
        
class Cloud(pygame.sprite.Sprite):
    ''' Creates the cloud sprite, places the top left corner of the rectangle at the given coordinates
    '''
    wind = 0
    def __init__(self, x_pos, y_pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image(CLOUD_IMAGE_FILENAME + random.choice('1234') + '.png')
        self.area = pygame.display.get_surface().get_rect()
        self.rect.topleft = (x_pos, y_pos)
    
    def update(self):
        ''' move self one pixel to the left
        '''
        if self.wind > 3:
            Cloud.wind = self.wind - 1
        if self.wind <-3:
            Cloud.wind = self.wind + 1
        self.rect.centerx -= self.wind
        
class ControlGui:
    ''' Sets up the control gui. This includes the Lumpy command, the sizing of the screen, and the definitions of wind and impact.
    '''
    def titlescreen(self):
        self.flag = False
        self.message= "Gorillas and Bananas"
        self.names3 = "Becky Scholl"
        self.names2 = "Katie Peters"
        self.names1 = "Elizabeth Kneen"
        self.date = "Spring 2007"
        BG_COLOR = (0,0,255) # Blue
        font = pygame.font.SysFont("courier",54)
        font2 = pygame.font.SysFont("courier",30)
        self.bg.fill(BG_COLOR, (0, 0, WIDTH, HEIGHT))
        
        self.text = font.render(self.message, 1, (255, 255, 255)) #White
        self.bg.blit(self.text, TEXT_POSITION)

        self.text = font2.render(self.names1, 1, (255, 255, 255)) #White
        self.bg.blit(self.text, (600,300))

        self.text = font2.render(self.names2, 1, (255, 255, 255)) #White
        self.bg.blit(self.text, (620,350))

        self.text = font2.render(self.names3, 1, (255, 255, 255)) #White
        self.bg.blit(self.text, (620,400))
        
        self.text = font2.render(self.date, 1, (255, 255, 255))
        self.bg.blit(self.text, (620, 450))

        self.contain2 = pgu.gui.Container(width=1400, height=1050)
        
        self.button_one = pgu.gui.Button('One Player')
        self.button_one.connect(pgu.gui.CLICK, self.button_press, self.button_one)
        self.contain2.add(self.button_one, 550, 600)
	
	self.button_two = pgu.gui.Button('Two Players')
        self.button_two.connect(pgu.gui.CLICK, self.button_press, self.button_two)
        self.contain2.add(self.button_two, 800, 600)

        self.pgui.init(self.contain2)
        self.screen.blit(self.bg, (0,0))
        self.pgui.paint(self.screen)

 #       self.gorilla_a_building = Building(0, random.randint(1225,1825))
 #       self.gorilla_b_building = Building(1200, random.randint(1225,1825))
 #       self.buildings = pygame.sprite.RenderPlain((self.gorilla_a_building, Building(200, random.randint(1600,1800)), Building(400, random.randint(1175,1825)), Building(600, random.randint(1175,1825)), Building(800, random.randint(1175,1825)), Building(1000, random.randint(1600, 1800)), self.gorilla_b_building))

        pygame.display.flip()
        pygame.mouse.set_visible(1)

        print 'beginning'
        while True:
            time.sleep(.1)
            for event in pygame.event.get():
                self.pgui.event(event)
            if self.flag:
                print 'break'
                break
            
    def __init__(self):
        self.turn = 'a'
        self.lumpy = Lumpy.Lumpy()
        self.lumpy.make_reference()
        pygame.init()
        pygame.font.init()
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT), 0)#pygame.FULLSCREEN)
        pygame.display.set_caption('PyGorillas')
        pygame.mouse.set_visible(1)
        self.bg = pygame.Surface(self.screen.get_size()).convert()
        self.pgui = pgu.gui.App()
        
        self.titlescreen()
        print 'out'
        self.bg.fill(BG_COLOR)
        self.screen.blit(self.bg, (0,0))
        #font = pygame.font.SysFont(*FONT)
        self.clouds = pygame.sprite.RenderPlain((Cloud(100, 35), Cloud(500, 30), Cloud(1000, 40), Cloud(1270, 30)))
        
        self.gorilla_a_building = Building(0, random.randint(1225,1825))
        self.gorilla_b_building = Building(1200, random.randint(1225,1825))
        self.buildings = pygame.sprite.RenderPlain((self.gorilla_a_building, Building(200, random.randint(1600,1800)), Building(400, random.randint(1175,1825)), Building(600, random.randint(1175,1825)), Building(800, random.randint(1175,1825)), Building(1000, random.randint(1600, 1800)), self.gorilla_b_building))
        
        self.gorilla_a = Gorilla(25, self.gorilla_a_building.rect.top)
        self.gorilla_b = Gorilla(1250, self.gorilla_b_building.rect.top)
        self.gorillas = pygame.sprite.RenderPlain((self.gorilla_a, self.gorilla_b))
        
        self.contain = pgu.gui.Container(width=1400, height=1050)
        
        self.button_a = pgu.gui.Button('go')
        self.button_a.connect(pgu.gui.CLICK, self.button_press, self.button_a)
        self.contain.add(self.button_a, 235, 985)
        
        self.button_b = pgu.gui.Button('go')
        self.button_b.connect(pgu.gui.CLICK, self.button_press, self.button_b)        
        
        self.vel_slider_a = pgu.gui.HSlider(value=50,min=0,max=100,size=20,width=150,height=16)
        self.vel_slider_b = pgu.gui.HSlider(value=50,min=0,max=100,size=20,width=150,height=16)
        self.ang_slider_a = pgu.gui.HSlider(value=45,min=0,max=90,size=20,width=150,height=16)
        self.ang_slider_b = pgu.gui.HSlider(value=45,min=0,max=90,size=20,width=150,height=16)
        self.vel_slider_a_lab = pgu.gui.Label('speed', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
        
        self.contain.add(self.vel_slider_a_lab, 5, 965)    
        self.ang_slider_a_lab = pgu.gui.Label('angle', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
        self.contain.add(self.ang_slider_a_lab, 5, 995) 
        self.vel_slider_b_lab = pgu.gui.Label('speed', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))       
        self.ang_slider_b_lab = pgu.gui.Label('angle', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))        
        self.contain.add(self.vel_slider_a, 75, 970)        
        self.contain.add(self.ang_slider_a, 75, 1005)
        
        self.button_AI = pgu.gui.Button('Go!')
        self.button_AI.connect(pgu.gui.CLICK, self.button_press, self.button_AI)
        self.pgui.init(self.contain)
        self.banana = Banana(self.bg, self.gorilla_a_building)       
        self.do_switch_players = False
        self.buildings_cubicles = [[[Rect(x, y, CUBICLE_WIDTH, CUBICLE_HEIGHT) for x in xrange(bld.rect.left, bld.rect.right, CUBICLE_WIDTH)] for y in xrange(1000, bld.rect.top, -CUBICLE_HEIGHT)] for bld in self.buildings]																																																																	
        self.damage_points = []

        
    def AI(self):
        if self.turn == 'a':
            self.turn = 'b'
            self.gorilla_a_building = Building(0, random.randint(1225,1825))
            self.gorilla_b_building = Building(1200, random.randint(1225,1825))
            self.buildings = pygame.sprite.RenderPlain((self.gorilla_a_building, Building(200, random.randint(1600,1800)), Building(400, random.randint(1175,1825)), Building(600, random.randint(1175,1825)), Building(800, random.randint(1175,1825)), Building(1000, random.randint(1600, 1800)), self.gorilla_b_building))
            self.vel_slider_AI = pgu.gui.HSlider(value=50,min=0,max=100,size=20,width=150,height=16)
            self.ang_slider_AI = pgu.gui.HSlider(value=45,min=0,max=90,size=20,width=150,height=16)
            self.vel_slider_AI_lab = pgu.gui.Label('speed', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
            self.ang_slider_AI_lab = pgu.gui.Label('angle', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
            self.button_AI = pgu.gui.Button('Go!')
#            self.AI.vel = random.randint(10,100)
 #           self.AI.ang = random.randint(10, 90)
            self.banana = Banana(self.bg, self.gorilla_a_building)       
        
            self.gorilla_a = Gorilla(25, self.gorilla_a_building.rect.top)
            self.gorilla_b = Gorilla(1250, self.gorilla_b_building.rect.top)
            self.gorillas = pygame.sprite.RenderPlain((self.gorilla_a, self.gorilla_b))
            self.button_a = pgu.gui.Button('go')

            self.button_press(self.button_AI)
            print 'AI'
            
        if self.turn == 'b':
           self.turn = 'a'
           if self.gorilla_b not in self.gorillas:
               self.gorilla_b.add(self.gorillas)
           if self.gorilla_a not in self.gorillas:
               self.gorilla_a.add(self.gorillas)
           self.contain = pgu.gui.Container(width=1400, height=1050)
           self.vel_slider_a = pgu.gui.HSlider(value=50,min=0,max=100,size=20,width=150,height=16)
           self.vel_slider_b = pgu.gui.HSlider(value=50,min=0,max=100,size=20,width=150,height=16)
           self.ang_slider_a = pgu.gui.HSlider(value=45,min=0,max=90,size=20,width=150,height=16)
           self.ang_slider_b = pgu.gui.HSlider(value=45,min=0,max=90,size=20,width=150,height=16)
           self.vel_slider_a_lab = pgu.gui.Label('speed', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
           self.ang_slider_a_lab = pgu.gui.Label('angle', font=pygame.font.SysFont(*FONT), color=(0, 0, 255))
           self.button_AI = pgu.gui.Button('Go!')
           self.button_a = pgu.gui.Button('go')
            
           self.contain.add(self.ang_slider_a, 75, 970)
           self.contain.add(self.vel_slider_a, 75, 1005)
           self.contain.add(self.vel_slider_a_lab, 5, 965)
           self.contain.add(self.ang_slider_a_lab, 5, 965)
           self.contain.add(self.button_a, 235, 985)
           print 'Player B'
#           self.contain.remove(self.button_AI)
        
    def button_press(self, button):
        if button is self.button_one:
            self.AI()
            self.flag = True

        elif button is self.button_two:
            pygame.display.flip()
            self.flag = True
            
        elif button is self.button_a:
            self.banana.dx = (self.vel_slider_AI.value)* math.cos((self.ang_slider_a.value * math.pi)/180)
            self.banana.dy = -(self.vel_slider_AI.value)* math.sin((self.ang_slider_a.value * math.pi)/180)


        elif button is self.button_AI:
            self.banana.dx = (self.vel_slider_a.value)*math.cos((self.ang_slider_a.value*math.pi)/180)
            self.banana.dy = -(self.vel_slider_a.value)*math.cos((self.and_slider_a.value*math.pi)/180)
            
        elif button is self.button_b:
            self.banana.dx = (self.vel_slider_b.value)* math.cos((self.ang_slider_b.value * math.pi)/180)
            self.banana.dy = -(self.vel_slider_b.value)* math.sin((self.ang_slider_b.value * math.pi)/180)
            
            
    def banana_update(self):
        print 'banana_update'
        if self.turn == 'a':
            self.banana.x += (self.banana.dx + Cloud.wind)
            self.banana.dy += 3
            self.banana.y += self.banana.dy
            
        elif self.turn == 'b':
            self.banana.x -= (self.banana.dx + Cloud.wind)
            self.banana.dy += 3
            self.banana.y += self.banana.dy
        
    def __call__(self):
        while True:
            time.sleep(.1)
            self.bg.fill(BG_COLOR, (0, 0, WIDTH, HEIGHT))
            if (abs(self.banana.dx) > 0.1) and (0 < self.banana.x < 1400):
                self.banana_update()
            if (self.banana.x < 0) or (self.banana.x > 1400): 
                self.banana.dx = 0
                self.do_switch_players = True
            self.draw()
            self.impact()
            self.screen.blit(self.bg, (0,0))
            self.pgui.paint(self.screen)
            
            if self.do_switch_players:
                self.switch_players()
                self.do_switch_players = False
            pygame.display.flip()
            self.wind()
            if self.quit():
                return
            for event in self.events:
                self.pgui.event(event)

            

            
    def switch_players(self):
        if self.turn == 'b':
            self.turn = 'a'
            if self.gorilla_a not in self.gorillas:
                self.gorilla_a.add(self.gorillas)
            if self.gorilla_b not in self.gorillas:
                self.gorilla_b.add(self.gorillas)
            self.contain.remove(self.vel_slider_b)
            self.contain.remove(self.ang_slider_b)
            self.contain.remove(self.ang_slider_b_lab)
            self.contain.remove(self.vel_slider_b_lab)
            self.contain.remove(self.button_b)
            self.contain.add(self.vel_slider_a, 75, 970)        
            self.contain.add(self.ang_slider_a, 75, 1005)
            self.contain.add(self.ang_slider_a_lab, 5, 995)
            self.contain.add(self.vel_slider_a_lab, 5, 965) 
            self.contain.add(self.button_a, 235, 985)
            self.banana.x = 125
            self.banana.y = (self.gorilla_a_building.rect.top - 95)
        elif self.turn == 'a':
            self.turn = 'b'
            if self.gorilla_a not in self.gorillas:
                self.gorilla_a.add(self.gorillas)
            if self.gorilla_b not in self.gorillas:
                self.gorilla_b.add(self.gorillas)
            self.contain.remove(self.ang_slider_a)
            self.contain.remove(self.vel_slider_a)
            self.contain.remove(self.vel_slider_a_lab)
            self.contain.remove(self.ang_slider_a_lab)
            self.contain.remove(self.button_a)
            self.contain.add(self.ang_slider_b, 1192, 1005)
            self.contain.add(self.vel_slider_b, 1192, 970)
            self.contain.add(self.ang_slider_b_lab, 1125, 995)
            self.contain.add(self.vel_slider_b_lab, 1125, 965)
            self.contain.add(self.button_b, 1355, 985)
            self.banana.x = 1200
            self.banana.y = self.gorilla_b_building.rect.top - 95
    
    def draw(self):
        self.clouds.draw(self.bg)
        self.sun = pygame.draw.circle(self.bg, (236, 236, 14), (700, 25), 25)
        self.buildings.draw(self.bg)
        for point in self.damage_points:
            pygame.draw.circle(self.bg, (0, 0, 255), point, 50)
        self.slider_panel = pygame.draw.rect(self.bg, (0, 0, 0), pygame.Rect(0, 950, 1400, 100), 0)
        self.gorillas.draw(self.bg)
        self.banana.draw(self.bg)
        
   
    def new_game(self):
        self.__init__()
    
    def end_game(self):
        if self.turn == 'a':
            self.message = "Player A Wins"
        elif self.turn == 'b':
            self.message = "Player B Wins"

        BG_COLOR = (0,0,255) # Blue
        font = pygame.font.SysFont("courier",54)
        self.bg.fill(BG_COLOR, (0, 0, WIDTH, HEIGHT))
        #self.pgui.paint(self.screen)

        self.text = font.render(self.message, 1, (255, 255, 255)) #White
        self.bg.blit(self.text, ((450), (200)))
 
        self.screen.blit(self.bg, (0,0))
        pygame.display.flip()
        time.sleep(2)
        self.new_game()

    def impact(self):
        for gorilla in self.gorillas:
            if self.banana.rect.colliderect(gorilla.rect):
                gorilla.remove(self.gorillas)
                self.banana.dx = 0
                self.end_game()
        for building_cubicle_i, building_cubicle in enumerate(self.buildings_cubicles[:]):
            for floor_i, floor in enumerate(building_cubicle):
                if len(floor) < 5:
                    bld = self.buildings.sprites()[building_cubicle_i]
                    if (bld is self.gorilla_a_building) or (bld is self.gorilla_b_building):
                        self.new_game()
                    pygame.draw.rect(
                        bld.image,
                        (0, 0, 255),
                        pygame.Rect(
                            0,
                            0,
                            200,
                            (building_cubicle[floor_i -1][0].y - bld.rect.y)
                        )
                    )
                    del building_cubicle[floor_i:]
                    break
                for cubicle in floor[:]:
                    if self.banana.rect.colliderect(cubicle):
                        self.banana.dx = 0
                        floor.remove(cubicle)
                        self.damage_points.append(self.banana.rect.center)
                        self.do_switch_players = True
        if self.banana.rect.colliderect(self.sun):
            pygame.draw.circle(self.bg, (0, 0, 255), (700, 25), 25)
            
    def diagrams(self):
        self.lumpy.object_diagram()
        self.lumpy.class_diagram()
            
    def wind(self):
        #the speed of the wind is redefined every time the main loop is called. 
        Cloud.wind += ((random.randrange(-10, 10, 1)) * .01)
        self.clouds.update()
        for cloud in self.clouds:
            if cloud.rect.left > 1400:
                cloud.remove(self.clouds)
                self.clouds.add(Cloud(-99, random.randint(20,30)))
            if cloud.rect.right < 0:
                cloud.remove(self.clouds)
                self.clouds.add(Cloud(1399, random.randint(20,30)))
            
    def quit(self):
        self.events = pygame.event.get()
        event_types = [event.type for event in self.events]
        event_keys = [event.key for event in self.events if event.type == KEYDOWN]
        if (QUIT in event_types) or (QUIT_KEY in event_keys):
            return True
        
ControlGui()()
#ControlGui().diagrams()
